from models.task import update_task
from flask import request
from algo.ml import kmeans, dbscan, pca, tsne
from common.database import OLAP
from common.utils.format_util import get_err_msg, err_formatter
import time
from flask import Blueprint
from common.log import log_handler

log = log_handler.LogHandler().get_log()

ml = Blueprint('ml', __name__)


def run(request, model):
    try:
        start_time = time.time()
        results = {}
        params = request.form.to_dict()
        log.info(params)

        source = params.get("source")
        target = params.get("target")
        taskId = params.get("taskId")
        cols = eval(params.get("cols"))
        params["cols"] = cols
        if len(cols) == 0:
            results["message"] = "请选择特征列"
            return str(results)

        if "." not in source:
            source = "dataset." + source
        sql = f"select * from {source}"
        df = OLAP.execute_query(sql)

        if model == "dbscan":
            df = dbscan.run(df, params)
        elif model == "kmeans":
            df = kmeans.run(df, params)
        elif model == "pca":
            df = pca.run(df, params)
        elif model == "tsne":
            df = tsne.run(df, params)
        log.info(f"algo time: {time.time() - start_time}")
    except Exception as e:
        return err_formatter(e)

    saved = OLAP.save_dataframe(target, df)
    updated = update_task(taskId, df, target, True)
    log.info(f"total time: {time.time() - start_time}")
    if saved and updated:
        return str(results)
    else:
        return get_err_msg()


@ml.route('/dbscan', methods=['POST'])
def dbscan_():
    return run(request, "dbscan")


@ml.route('/kmeans', methods=['POST'])
def kmeans_():
    return run(request, "kmeans")


@ml.route('/pca', methods=['POST'])
def pca_():
    return run(request, "pca")


@ml.route('/tsne', methods=['POST'])
def tsne_():
    return run(request, "tsne")
